package com.orifine.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;


/**
 * 用于处理action提交一系列过程的流程信息处理
 * 
 * @author Administrator
 * 
 */
@Service
@Scope("request")
public class ActionFrom {
	private Set<String> messageList = new HashSet<String>();

	public void addMessage(String message) {
		messageList.add(message);
	}

	public boolean hasMessage(String message) {
		return messageList.contains(message);
	}

	private Map<String, List<Validator>> validatorListMap = new LinkedHashMap<String, List<Validator>>();
	private List<Validator> validatorAll = new ArrayList<Validator>();
	private Map<Validator, String> validatorMap = new HashMap<Validator, String>();

	public void addValidator(String domain, Validator validator, Object... values) {
		List<Validator> validatorList = validatorListMap.get(domain);
		if (validatorList == null) {
			validatorList = new ArrayList<Validator>();
			validatorListMap.put(domain, validatorList);
			domainNextMap.put(domain, -1);
		}
		Validator newValidator = validator.define(values);
		validatorList.add(newValidator);
		validatorAll.add(newValidator);
		validatorMap.put(validator, domain);
	}

	public void addValidator(String domain, Validator[] validators, Object... values) {
		for (Validator validator : validators) {
			addValidator(domain, validator, values);
		}
	}

	public Iterator<String> domainIterator() {
		return validatorListMap.keySet().iterator();
	}

	public Iterator<Validator> validateIterator(String domain) {
		List<Validator> validatorList = validatorListMap.get(domain);
		if (validatorList == null)
			return null;
		return validatorList.iterator();
	}

	private int next = -1;

	public boolean hasNext() {
		return hasMove(next + 1);
	}

	private boolean hasMove(int move) {
		if(move >= validatorAll.size()){
			return false;
		}
		
		Validator validator = validatorAll.get(move);
		if (!validator.result()) {
			return true;
		} else {
			String domain = validatorMap.get(validator);
			List<Validator> validatorList = validatorListMap.get(domain);
			if (validatorList.size() <= 1) {
				validatorListMap.remove(domain);
				domainNextMap.remove(domain);
			} else {
				validatorList.remove(validator);
			}
			validatorMap.remove(validator);
			validatorAll.remove(validator);
			return hasMove(move);
		}
	}

	public Validator next() {
		if (!hasNext()) {
			return null;
		} else {
			return validatorAll.get(++next);
		}
	}
	
	public void reset() {
		next = -1;
	}
	
	private Map<String, Integer> domainNextMap = new HashMap<String, Integer>();
	
	public boolean hasNext(String domain){
		Integer next = domainNextMap.get(domain);
		if(next == null){
			return false;
		}
		return hasMove(domain, next+1);
	}
	
	private boolean hasMove(String domain, int move) {
		List<Validator> validatorList = validatorListMap.get(domain);
		if(move >= validatorList.size()){
			return false;
		}
		
		Validator validator = validatorList.get(move);
		if (!validator.result()) {
			return true;
		} else {
			if (validatorList.size() <= 1) {
				validatorListMap.remove(domain);
				domainNextMap.remove(domain);
			} else {
				validatorList.remove(validator);
			}
			validatorMap.remove(validator);
			validatorAll.remove(validator);
			if(move <= this.next){
				-- this.next;
			}
			return hasMove(domain, move);
		}
	}
	
	public Validator next(String domain){
		if(!hasNext(domain)){
			return null;
		} else {
			Integer next = domainNextMap.get(domain) + 1;
			domainNextMap.put(domain, next);
			return validatorListMap.get(domain).get(next);
		}
	}
	
	public void reset(String domain){
		if(domainNextMap.get(domain) != null){
			domainNextMap.put(domain, -1);
		}
	}
}
